package router

import (
	"Walker/pkg/contract"
	"Walker/pkg/request"
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
)

type Router struct {
	app    contract.Application
	gin    *gin.Engine
	config contract.Config
	routes []contract.Route
	groups []contract.GroupRouter
	middle []contract.MagicFunc
}

//给路由分组

func (router *Router) Group(path string) contract.GroupRouter {
	group := (&GroupRouter{app: router.app}).NewGroup(path)
	//存放
	router.groups = append(router.groups, group)
	return group
}
func (router *Router) Get(url string, action interface{}) contract.Router {
	router.Add(http.MethodGet, url, action)
	return router
}
func (router *Router) Post(url string, action interface{}) contract.Router {
	router.Add(http.MethodPost, url, action)
	return router
}
func (router *Router) Put(url string, action interface{}) contract.Router {
	router.Add(http.MethodPut, url, action)
	return router
}
func (router *Router) Delete(url string, action interface{}) contract.Router {
	router.Add(http.MethodDelete, url, action)
	return router
}
func (router *Router) Use(middle ...interface{}) contract.Router {
	//组装中间件
	router.middle = append(router.middle, router.app.CreateMagicFunc(middle))
	return router
}
func (router *Router) Add(method string, url string, action interface{}) {
	router.routes = append(router.routes, &Route{
		method: method,
		url:    url,
		action: router.app.CreateMagicFunc(action),
	})
}
func (router *Router) Start() error {
	//把路由装填到gin服务当中启动路由
	router.FillingRoute(router.routes)
	//分组的路由处理
	router.AnalyseGroup(router.groups)

	return router.gin.Run(router.config.GetString("app.http.port"))
}
func (router *Router) FillingRoute(routers []contract.Route) {
	for _, value := range routers {
		fmt.Println(value.Url())
		router.gin.Handle(value.Method(), value.Url(), router.HandlerFunc(value.Action()))
	}
}
func (router *Router) AnalyseGroup(groups []contract.GroupRouter) {
	for _, value := range groups {
		router.FillingRoute(value.Routes())
		if len(value.Groups()) > 0 {
			router.AnalyseGroup(value.Groups())
		}
	}
}
func (router *Router) HandlerFunc(action interface{}) gin.HandlerFunc {
	return func(context *gin.Context) {
		req := request.CreateRequest(context)
		result := router.app.MagicFuncCall(action, func() contract.Request {
			return req
		})
		//处理响应结构
		router.HandlerResponse(req, result)
	}
}

func (router *Router) HandlerResponse(request contract.Request, response interface{}) {
	//
	//request.Context().(*gin.Context).JSON(200, tem)
	switch tem := response.(type) {
	case contract.Response:
		//标准返回
		request.Context().(*gin.Context).JSON(tem.GetStatus(), tem.ToJson())
	default:
		request.Context().(*gin.Context).JSON(200, response)
	}
}
